#pragma once

#include <FileUtil.h>
#include <Timestamp.h>
#include <iostream>
#include <mutex>
#include <memory>

namespace AsyncLogger {

	/// <summary>
	/// 对AppendFile进行一层封装
	/// </summary>
	class LogFile {
		using time_p = long long; // time point

	public:
		LogFile(const std::string logDirPath, const std::string& basename, off_t rollSize, bool threadSafe = false, int flushInterval = 3, int checkEveryN = 1024);

		/// <summary>
		/// 刷新缓冲区
		/// </summary>
		void flush();

		/// <summary>
		/// 滚动文件
		/// </summary>
		void rollFile();

		/// <summary>
		/// 写入一条log，同时根据写入大小、写入时间rollFile
		/// </summary>
		/// <param name="logline"></param>
		/// <param name="len"></param>
		void append(const char* logline, int len);

		~LogFile() = default;
	private:

		/// <summary>
		/// 不加锁写入一条log，同时根据写入大小、写入时间rollFile
		/// </summary>
		/// <param name="logline"></param>
		/// <param name="len"></param>
		void append_unlocked(const char* logline, size_t len);

		/// <summary>
		/// 获取精度为s的时间戳（chrono默认获取的count是ns级别的，需要手动转换）
		/// </summary>
		/// <returns></returns>
		time_p getTimestamp();

		/// <summary>
		/// 获取文件名，文件名格式：程序名.时间.主机名.pid.log
		/// </summary>
		/// <param name="now"></param>
		/// <returns></returns>
		std::string getLogFilename(time_p& now);

	private:
		long long count_;
		const int checkEveryN_;
		const int flushInterval_;
		std::unique_ptr<std::mutex> mutex_;
		const off_t rollSize_;
		std::string logDirPath_;
		std::string basename_;
		std::unique_ptr<FileUtil::AppendFile> file_;
		time_p lastFlush_;
		time_p startOfPeriod_;
		time_p lastRoll_;

		const static int kRollPerSeconds_ = 60 * 60 * 24; // 滚动周期，至少一天滚动一次
	};
}